package org.util;

import org.Entity.Student;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.Properties;

/**
 * 数据库工具类
 */
public class DBUtil {
    private static final String driverClassName;
    private static final String url;
    private static final String username;
    private static final String password;

    static {
        //静态加载properties文件，获取里面的值
        Properties properties = new Properties();
        try {
            InputStream resourceAsStream = DBUtil.class.getClassLoader().getResourceAsStream("");
            properties.load(resourceAsStream);
            if (resourceAsStream != null) {
                resourceAsStream.close();
            }
//            driverClassName = properties.getProperty("driverClassName");
//            url = properties.getProperty("url");
//            username = properties.getProperty("username");
//            password = properties.getProperty("password");
            driverClassName = "com.mysql.cj.jdbc.Driver";
            url = "jdbc:mysql://localhost:3306/test";
            username = "root";
            password = "";
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接
     */
    public static Connection getConnection() {
        Connection connection;
        try {
            if (driverClassName != null && !driverClassName.isEmpty()) {
                Class.forName(driverClassName);
            }
            connection = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException | SQLException e) {
            throw new RuntimeException(e);
        }
        return connection;
    }

    /**
     * 关闭释放资源
     *
     * @param resultSet         释放结果集资源
     * @param preparedStatement 释放预处理资源
     * @param connection        关闭数据库连接
     */
    public static void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (preparedStatement != null) {
                preparedStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    public static Object select4Bean(Class<?> beanClass, Map<String,?> cond){
        StringBuilder sql = new StringBuilder("select ");
        String name = beanClass.getSimpleName();
        Field[] fs = beanClass.getDeclaredFields();
        for (Field f : fs) {
            sql.append(f.getName()).append(",");
        }
        sql = new StringBuilder(sql.substring(0, sql.length() - 1));
        sql.append(" from ").append(name);
        if (cond != null && !cond.isEmpty()) {
            sql.append(" where ");
            int index = 0;
            for (String key : cond.keySet()) {
                sql.append(key).append(" = ?");
                if (index < cond.size() - 1) {
                    sql.append(" and ");
                }
                index++;
            }
        }
        return getObjects(beanClass, sql);
    }

    private static ArrayList<Object> getObjects(Class<?> beanClass, StringBuilder sql) {
        Connection connection = getConnection();
        ArrayList<Object> params = new ArrayList<>();
        PreparedStatement pst = null;
        try {
            pst = connection.prepareStatement(String.valueOf(sql));
            ResultSet rs = pst.executeQuery();
            while (rs.next()) {
                Constructor<?> constructor = beanClass.getConstructor(String.class,int.class,double.class);
                Object obj = constructor.newInstance(
                        rs.getString(1),
                        rs.getInt(2),
                        rs.getDouble(3)
                ) ;
                params.add(obj);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            close(null, pst, connection);
        }
        return params;
    }
    public static int insert(Object bean) {
        String sql = "";
        try {
            Class<?> beanClass = bean.getClass();
            String tableName = beanClass.getSimpleName();

            StringBuilder columns = new StringBuilder("(");
            StringBuilder values = new StringBuilder("(");
            Field[] fields = beanClass.getDeclaredFields();

            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);

                columns.append(field.getName());

                Object value = field.get(bean);
                if (value == null) {
                    values.append("NULL");
                } else if (value instanceof String || value instanceof Date) {
                    values.append("'").append(value).append("'");
                } else {
                    values.append(value);
                }

                if (i < fields.length - 1) {
                    columns.append(", ");
                    values.append(", ");
                }
            }

            columns.append(")");
            values.append(")");

            sql = "insert into " + tableName + " " + columns + " values " + values;

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return insertSql(bean, sql);
    }
    private static int insertSql(Object bean, String sql) {
        Connection conn = getConnection();
        PreparedStatement pst = null;
        int result = 0;
        try {
            pst = conn.prepareStatement(sql);
            result = pst.executeUpdate();
            if (result > 0) {
                System.out.println("插入成功");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            close(null, pst, conn);
        }
        return result;

    }
}
